/*
 *  Copyright (C) 2010 Francesco Boffa (aka AlfaOmega08)
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ImageFormats.Iso9660;

import java.io.*;

public class PrimaryVolumeDescriptor {
	private byte Type;
	private String Identification;
	private byte Version;
	private String SystemId;
	private String VolumeId;
	private BothEndianDWord VolumeSpaceSize;
	private BothEndianWord VolumeSetSize;
	private BothEndianWord VolumeSequenceNumber;
	private BothEndianWord LogicalBlockSize;
	private BothEndianDWord PathTableSize;
	private int FirstLePathTable;
	private int SecondLePathTable;
	private int FirstBePathTable;
	private int SecondBePathTable;
	private DirectoryRecord RootDirectory = new DirectoryRecord();
	private String VolumeSetId;
	private String PublisherId;
	private String DataPreparerId;
	private String ApplicationId;
	private String CopyrightFileId;
	private String AbstractFileId;
	private String BiblioFileId;
	private DateTime Creation = new DateTime();
	private DateTime LastEdit = new DateTime();
	private DateTime Expiration = new DateTime();
	private DateTime Effective = new DateTime();

	public void getFromStream(RandomAccessFile f) {
		try {
			Type = f.readByte();
			if (Type != 1) {
				System.out.println("Programming error");
				System.exit(-1);
			}

			byte[] tmp = new byte[5];
			f.read(tmp, 0, 5);
			Identification = new String(tmp, 0, 5);
			if (!Identification.equals(new String("CD001"))) {
				System.out.println("Invalid ISO Filesystem: Wrong identification");
				System.exit(-1);
			}

			Version = f.readByte();
			f.skipBytes(1);

			tmp = new byte[32];
			f.read(tmp, 0, 32);
			SystemId = new String(tmp, 0, 32);
			f.read(tmp, 0, 32);
			VolumeId = new String(tmp, 0, 32);

			f.skipBytes(8);

			tmp = new byte[8];
			f.read(tmp, 0, 8);
			VolumeSpaceSize = new BothEndianDWord(tmp);

			f.skipBytes(32);

			tmp = new byte[4];
			f.read(tmp, 0, 4);
			VolumeSetSize = new BothEndianWord(tmp);

			f.read(tmp, 0, 4);
			VolumeSequenceNumber = new BothEndianWord(tmp);

			f.read(tmp, 0, 4);
			LogicalBlockSize = new BothEndianWord(tmp);

			tmp = new byte[8];
			f.read(tmp, 0, 8);
			PathTableSize = new BothEndianDWord(tmp);

			FirstLePathTable = Integer.reverseBytes(f.readInt());
			SecondLePathTable = Integer.reverseBytes(f.readInt());

			/* TODO: check wheter this works on big endian machines */
			FirstBePathTable = f.readInt();
			SecondBePathTable = f.readInt();

			RootDirectory.getFromStream(f);

			tmp = new byte[128];
			f.read(tmp, 0, 128);
			VolumeSetId = new String(tmp);
			f.read(tmp, 0, 128);
			PublisherId = new String(tmp);
			f.read(tmp, 0, 128);
			DataPreparerId = new String(tmp);
			f.read(tmp, 0, 128);
			ApplicationId = new String(tmp);

			tmp = new byte[37];
			f.read(tmp, 0, 37);
			CopyrightFileId = new String(tmp, 0, 37);
			f.read(tmp, 0, 37);
			AbstractFileId = new String(tmp, 0, 37);
			f.read(tmp, 0, 37);
			BiblioFileId = new String(tmp, 0, 37);

			Creation.getFromAsciiStream(f);
			LastEdit.getFromAsciiStream(f);
			Expiration.getFromAsciiStream(f);
			Effective.getFromAsciiStream(f);
		} catch (IOException e) {
			System.out.println("IOException while parsing the Primary Volume Descriptor: " + e.getMessage());
		}
	}

	DirectoryRecord getRootDirectoryRecord() {
		return RootDirectory;
	}
}
